Spring Framework의 핵심 기능 중 하나인 의존성 주입(DI) 은 객체 간의 의존 관계를 스프링 컨테이너가 자동으로 연결해 주는 개념입니다.
DI를 통해 객체 간 결합도를 낮추고, 테스트가 용이하며, 변경에 유연한 설계를 가능하게 합니다.
객체가 의존하는 다른 객체를 직접 생성하지 않고, 외주에서 주입(Injection)받는 방식.
Spring에서는 주로 다음 3가지 방식으로 의존성을 주입합니다.
@Component
public class OrderService {
private final MemberRepository memberRepository;
@Autowired // 생략 가능 (생성자가 1개면)
public OrderService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
📌 장점
✅final
키워드 사용 가능 → 불변 보장
✅ 필수 의존성 보장 (컴파일 시정에 체크)
✅ 테스트 시 Mock 주입이 쉬움
코드가 짧고 간단하지만, 테스트 어려움 + 순환 참조 위험
@Component
public class OrderService {
@Autowired
private MemberRepository memberRepository;
}
📌 단점
❌final
사용 불가
❌ DI가 프레임워크에 종속됨 (테스트 시 DI 불가)
❌ 의존성 주입이 외부에서 불가능해짐 → 테스트 유연성 떨어짐
@Component
public class OrderService {
private MemberRepository memberRepository;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
🧐 사용 예:
@ConfigurationProperties
, 외부 설정을 받아야 하는 객체 등
스프링 컨테이너가 관리하는 객체를 스프링 빈이라고 하며, DI를 통해 빈들 간의 의존성을 연결합니다.
@Service
public class MemberService { ... }
@Repository
public class MemberRepository { ... }
✔️ 컴포넌트 스캔을 통해 등록된 클래스들은 자동으로 스프링 빈이 되고, 의존성 주입 대상이 됨
MemberService
→ MemberRepository
에 의존@Service
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
public String getMember(Long id) {
return memberRepository.findNameById(id);
}
}
@Repository
public class MemberRepository {
public String findNameById(Long id) {
return "User" + id;
}
}
✔️ MemberService는 MemberRepository
가 필요하지만 직접 생성하지 않음
✔️ 스프링이 자동으로 생성 후, 주입